const {readFileSync} = require("fs");

/**
 * 常用工具类
 *
 */
class MUtils {

    /**
     * 不为空值
     *
     * @param t
     * @return {boolean}
     */
    static isNotEmpty(t) {
        return !MUtils.isEmpty(t);
    }

    /**
     * 为空值
     *
     * @param t
     * @return {boolean}
     */
    static isEmpty(t) {
        return t === undefined || t == null || t === '';
    }

    /**
     * 如果为空时，设置默认值
     *
     * @param t
     * @param defaultVal
     * @return {*}
     */
    static defaultIfEmpty(t, defaultVal) {
        if (MUtils.isEmpty(t)) {
            return defaultVal;
        }
        return t;
    }

    /**
     * 取绝对值
     *
     * @param t
     * @return {*|number}
     */
    static abs(t) {
        if (MUtils.isNotEmpty(t)) {
            return Math.abs(t);
        }
        return t;
    }

    /**
     * 判断是否是json对象
     *
     * @param text
     * @return {boolean}
     */
    static isValidJSON(text) {
        try {
            JSON.parse(text);
            return true;
        } catch (error) {
            return false;
        }
    }

    /**
     * 判断是否是数组
     *
     * @param obj
     * @return {boolean}
     */
    static isJsonArray(obj) {
        return obj instanceof Array;
    }

    /**
     * 读取json文件
     *
     * @param path
     * @return {any}
     */
    static getJson(path) {
        const data = readFileSync(path, 'utf8');
        return JSON.parse(data);
    }

    /**
     * 获取json的key值
     *
     * @param json
     * @return {[]|null}
     */
    static getJsonKeys(json) {
        if (json == null) {
            return null;
        }
        const keys = [];
        for (const key in json) {
            keys.push(key);
        }
        return keys;
    }

    /**
     * 获取json的value值
     *
     * @param json
     * @return {[]|null}
     */
    static getJsonValues(json) {
        if (json == null) {
            return null;
        }
        const values = [];
        for (const key in json) {
            values.push(json[key]);
        }
        return values;
    }

    /**
     * 转换json对象
     *
     * @param jsonStr
     * @return {{}}
     */
    static parseJson(jsonStr) {
        return JSON.parse(jsonStr);
    }

    /**
     * 字符串相似度匹配
     *
     * @param s1
     * @param s2
     * @return {number}
     */
    static similarity(s1, s2) {
        let longer = s1;
        let shorter = s2;
        if (s1.length < s2.length) { // longer should always be greater
            longer = s2;
            shorter = s1;
        }
        let longerLength = longer.length;
        if (longerLength === 0) {
            return 1.0;
        }
        // Create an array of sizes, from 0 up to the length of the longer string.
        let matrix = Array(longerLength + 1).fill(0).map(() => Array(shorter.length + 1).fill(0));

        // Fill the first row
        for (let i = 0; i <= shorter.length; i++) {
            matrix[0][i] = i;
        }

        // Fill the first column
        for (let j = 0; j <= longer.length; j++) {
            matrix[j][0] = j;
        }

        // Iterate over the matrix
        for (let i = 1; i <= longer.length; i++) {
            let char1 = longer.charAt(i - 1);
            for (let j = 1; j <= shorter.length; j++) {
                let char2 = shorter.charAt(j - 1);
                if (char1 === char2) {
                    matrix[i][j] = matrix[i - 1][j - 1];
                } else {
                    matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
                        Math.min(matrix[i][j - 1] + 1, // insertion
                            matrix[i - 1][j] + 1)); // deletion
                }
            }
        }
        return 1 - matrix[longerLength][shorter.length] / longerLength;
    }

    /**
     * 获取当前时间
     */
    static getCurrentTime() {
        const {year, month, day, hour, minute, second} = MUtils.getTimeJson(null, null);
        return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    }

    /**
     * 获取时间json
     *
     *
     * @param timestamp
     * @param offset
     * @return {{month: string, hour: string, year: string, day: string, minute: string, second: string}}
     */
    static getTimeJson(timestamp, offset) {
        let currentTime;
        if (timestamp != null) {
            currentTime = new Date(timestamp);
        } else {
            currentTime = new Date();
        }
        if (offset != null) {
            currentTime.setDate(currentTime.getDate() + offset);
        }
        const year = currentTime.getFullYear().toString(); // 四位数表示的年份
        const month = (currentTime.getMonth() + 1).toString().padStart(2, '0'); // 两位数表示的月份（注意要加上1）
        const day = currentTime.getDate().toString().padStart(2, '0'); // 两位数表示的日期
        const hour = currentTime.getHours().toString().padStart(2, '0'); // 两位数表示的小时
        const minute = currentTime.getMinutes().toString().padStart(2, '0'); // 两位数表示的分钟
        const second = currentTime.getSeconds().toString().padStart(2, '0'); // 两位数表示的秒数
        return {year, month, day, hour, minute, second};
    }

    /**
     * UTC时间字符串转换为时间戳
     *
     * @param utcString
     * @return {number}
     */
    static convertUTCToTimestamp(utcString) {
        return Date.parse(utcString);
    }

    /**
     * UTC时间转换
     *
     * @param utcString
     * @return {{month: string, hour: string, year: string, day: string, minute: string, second: string}}
     */
    static convertUTCToDateJson(utcString) {
        const timestamp = MUtils.convertUTCToTimestamp(utcString);
        return MUtils.getTimeJson(timestamp, null);
    }

    /**
     * 比较两个值
     * <br> i1 > i2 则返回正数，i1 < i2 则返回负数，相等返回0
     *
     * @param i1
     * @param i2
     */
    static compare(i1, i2) {
        if (MUtils.isEmpty(i1) || MUtils.isEmpty(i2)) {
            return 0;
        }
        return eval(i1) - eval(i2);
    }

    /**
     * 复制对象
     *
     * @param obj
     * @return {any}
     */
    static copy(obj) {
        return JSON.parse(JSON.stringify(obj));
    }

    /**
     * 获取随机整数
     *
     * @param min
     * @param max
     * @returns {number}
     */
    static getRandomInt(min, max) {
        min = Math.ceil(min);//向上取整
        max = Math.floor(max); //向下取整
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
}

module.exports = {
    MUtils
};